package com.l.web.action.site;

import com.l.web.action.system.module.ModuleInterface;
import com.l.web.service.system.config.Config;
import com.l.web.service.system.module.ModuleDAO;
import com.l.web.service.system.webnode.WebNodeDAO;
import com.l.web.service.webcontent.WebContent;
import org.l.qiao.Cluster;
import org.l.qiao.Template;
import org.l.qiao.check.Check;
import org.l.qiao.dao.TemplateDAO;
import com.l.web.service.webcontent.WebContentDAO;
import org.l.qiao.search.Query;
import org.l.qiao.search.Sort;
import org.l.qiao.search.TemplateSearch;
import com.l.web.service.system.config.ConfigDAO;
import com.l.web.service.system.extension.Extension;
import com.l.web.service.system.extension.ExtensionDAO;
import com.l.web.service.system.module.Module;
import com.l.web.service.system.webnode.WebNode;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import org.apache.log4j.Logger;
import org.apache.struts2.interceptor.ServletResponseAware;
import org.apache.struts2.util.ServletContextAware;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class Index extends ActionSupport implements ServletResponseAware, ServletContextAware {

    /**
     *
     */
    private static final long serialVersionUID = 9013847648190226219L;
    private ConfigDAO configdao;
    private ModuleDAO moduledao;
    private ExtensionDAO extensiondao;
    private WebNodeDAO channeldao;
    private WebContentDAO channelcontentdao;
    private TemplateDAO templatedao;

    private Config systemconfig;

    private HttpServletResponse res = null;
    private WebApplicationContext wac;
    private static final Logger LOGGER = Logger.getLogger(Index.class);

    private String channelid = "";
    private String contentid = "";
    private WebNode webNode;
    private WebContent channelcontent;
    private Template template;
    private Map<String, List<Module>> positions = new HashMap<String, List<Module>>();
    private ActionContext context;

    private Map<String, Object> data = new HashMap<String, Object>();

    public void setConfigdao(ConfigDAO configdao) {
        this.configdao = configdao;
    }

    public void setModuledao(ModuleDAO moduledao) {
        this.moduledao = moduledao;
    }

    public void setExtensiondao(ExtensionDAO extensiondao) {
        this.extensiondao = extensiondao;
    }

    public void setChanneldao(WebNodeDAO channeldao) {
        this.channeldao = channeldao;
    }

    public void setChannelcontentdao(WebContentDAO channelcontentdao) {
        this.channelcontentdao = channelcontentdao;
    }

    public void setTemplatedao(TemplateDAO templatedao) {
        this.templatedao = templatedao;
    }

    public void setChannelid(String channelid) {
        this.channelid = channelid;
    }

    public void setContentid(String contentid) {
        this.contentid = contentid;
    }

    public void setServletResponse(HttpServletResponse res) {
        this.res = res;
    }

    @Override
    public void setServletContext(ServletContext servletContext) {
        wac = WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext);
    }

    public Config getSystemconfig() {
        return systemconfig;
    }

    public String execute() throws IOException {
        LOGGER.info("访问栏目信息ID：channelid=" + channelid + ",contentid=" + contentid);
        context = ActionContext.getContext();
        String status = SUCCESS;
        Check check = new Check();
        if ((check.checkId(channelid) || channelid.length() == 0) && (check.checkId(contentid) || contentid.length() == 0)) {
            Query query = new Query();
            if (channelid.length() == 0) {
                query.eq(WebNode.DEFAULT, 1);
            } else {
                query.idEQ(channelid);
            }
            webNode = new WebNode(channeldao.findOne(query));
            if (webNode.isEmpty()) {
                res.sendError(404);
                LOGGER.error("非法访问，无效栏目：channelid=" + channelid + ",contentid=" + contentid);
                return NONE;
            }
            LOGGER.debug("栏目信息：" + webNode);
            String tid = webNode.getString(WebNode.TEMPLATE_ID, null);
            TemplateSearch ts = new TemplateSearch();
            if (tid == null) {
                ts.defaultEQ(1);
            } else {
                ts.idEQ(tid);
            }
            template = new Template(templatedao.findOne(ts));
            if (template.isEmpty()) {
                res.sendError(404);
                LOGGER.error("栏目配置错误，找不到模板：channelid=" + channelid + ",templateid=" + tid);
                return NONE;
            }
            LOGGER.debug("模板信息：" + template);
            for (String p : template.getPosition()) {
                positions.put(p, new ArrayList<Module>());
            }
            LOGGER.debug("模板模块信息：" + positions);
            context.put("position", positions);
            if (contentid.length() > 0) {
                channelcontent = new WebContent(channelcontentdao.findById(contentid));
                if (channelcontent.isEmpty()) {
                    res.sendError(404);
                    LOGGER.error("非法访问，无效内容：channelid=" + channelid + ",contentid=" + contentid);
                    return NONE;
                }
            }
            status = loadModule();
            LOGGER.debug("所有模块内容：" + positions);
        } else {
            res.sendError(404);
            LOGGER.error("非法访问，错误ID：channelid=" + channelid + ",contentid=" + contentid);
            return NONE;
        }
        return status;
    }

    private void appendModule(String position, Module mod) {
        List<Module> list = positions.get(position);
        if (list != null)
            list.add(mod);
        LOGGER.debug("装载模块内容：" + mod);
    }

    private String loadModule() {
        Module mod = new Module();
        Query query = new Query();
        query.eq(Module.CHANNEL, webNode.getId());
        Sort sort = new Sort();
        sort.desc(Module.INDEX);
        List<Cluster> modules = moduledao.find(query, null, sort);
        for (Map<String, Object> map : modules) {
            mod.clear();
            mod.putAll(map);
            String extkey = mod.getString(Module.EXT_KEY, null);
            query.clear();
            Extension ext = new Extension();
            query.eq(Extension.KEY, extkey);
            ext.putAll(extensiondao.findOne(query));
            if (ext.isEmpty()) {
                LOGGER.error("模块加载错误，扩展不存在：channelid=" + channelid + ",contentid=" + contentid + ",moduleid=" + mod.getId() + ",extensionkey=" + extkey);
                continue;
            }
            mod.put(Module.EXT, ext);
            mod.formatOption();
            String bean = ext.getString(Extension.BEAN, "");
            try {
                ModuleInterface modinter = (ModuleInterface) wac.getBean(bean);
                modinter.setModule(mod);
                String tmp = modinter.execute();
                appendModule(mod.getString(Module.POSITION, ""), mod);
                if (tmp != null)
                    return tmp;
            } catch (Exception e) {
                LOGGER.error("模块执行异常(channelid=" + channelid + ",contentid=" + contentid + ",moduleid=" + mod.getId() + ",bean=" + bean + ")：" + e.getMessage());
            }
        }
        return SUCCESS;
    }

    public Map<String, Object> getData() {
        return data;
    }
}
